#ifndef __GE_GUIBASE_H__
#define __GE_GUIBASE_H__

#include "GE_Base.h"
namespace Syp
{
	///GuiBase is the base class from which all GUI components inherit from.It contains basic functionality required by all GUI Components to function.
	class SYPAPI GuiBase
	{
	public:
		//Following are Events which can be customised per instance.
		boost::signal<void (GuiBase*)> onMouseOver;
		boost::signal<void (GuiBase*)> onMouseOut;
		boost::signal<void (GuiBase*)> onMouseLeftDown;
		boost::signal<void (GuiBase*)> onMouseLeftUp;
		boost::signal<void (GuiBase*)> onMouseRightDown;
		boost::signal<void (GuiBase*)> onMouseRightUp;
		boost::signal<void (GuiBase*)> onMouseMove;		

		///The following are virtual functions which can be overloaded to define what happens when triggered for all objects of the class type. 
		//Defines what should always happen to the component of that type onMouseClick
		virtual void mouseLeftDown();
		virtual void mouseRightDown();
		//Defines what should always happen to the component of that type onMouseOut
		virtual void mouseOut(){};
		//Defines what should always happen to the component of that type onMouseUp
		virtual void mouseLeftUp();
		virtual void mouseRightUp();
		virtual void mouseOver(){};
		//Defines what will happen when the mouseMoves. GuiComponent must first subscribe to mouse updates from InputManager for this to have any effect.
		virtual void mouseMove(const MouseState& ms){};
		///Returns a reference to the Components MeshInstance
		MeshInstance& getMIRef();
		///InputManager will call this function to inform the component of the mouse's status. 
		void recieveMouseInfo(const MouseState& ms, MouseEvent me);
		///Sets the Texture for GuiComponent
		void useTexture(const String& filename);
		///Sets the Texture for GuiComponent
		void useTexture(TextureObj* tex);
		///Sets the UVCoord for the button.
		void setUVCoord(float u1,float v1, float width, float height);
		///Returns true if mouse is within boundaries of Component
		bool isMouseIn();
		///Returns true if Component was left-clicked on
		bool isLeftDepressed();
		///Sets the MouseFocus to a GuiBase element
		static void setMouseFocus(GuiBase* gb);
		///Returns the GuiBase element which currently has the mouseFocus.
		static GuiBase* getMouseFocus();

		static void destroyGuiComponent(GuiBase* gb);
	protected:
		//We want to force the use of factory like static functions for creation/destuction of Gui components to prevent DLL related memory problems. Name specifies a unique name for the component. genMesh boolean indicates whether constructor should generate the default mesh.
		GuiBase(const String& Name,float Width, float Height, bool genmesh = true);
		virtual ~GuiBase();
		///The mesh of the Gui component
		NIndexedMesh* mesh;
		///The mesh instance of the Gui component
		MeshInstance* mi;
		///Material for Gui component
		Material* mat;
		///Generates and updates the mesh. Can be overloaded for custom looking Gui Components.
		virtual void genMesh();

		bool mouseIsIn;	

		float height;
		float width;
		String name;
	


	private:
		bool visible;
		///This will cause the Component to be clipped within the parent's rectangular area of influence.
		bool clipToParent;
		///Current GuiBase element with focus
		static GuiBase* mouseFocus;



  

	};

}
#endif //__GE_GUIBASE_H__
